//  用于封装常用方法和公共业务
import { Models } from '@/common/typings/modle'
import pool from '@/server/mysql/pool'
import { DataBaseFailed } from '@/core/HttpException'

import { lineToHumpObject } from '@/common/utils/utils'

import mysql from 'mysql'
import logger from '@/server/logs/logger'

/**
 * 执行sql
 * @param command sql语句
 * @param useLog 是否记录log 默认不记录
 * @param value 中间件 默认为空
 */
export async function command(command: string, useLog = false, value?: Array<any> | boolean): Promise<Models.Result> {
  command = command.replace(/,\s*/g, ', ').replace(/\s+/g, ' ')
  try {
    return new Promise<Models.Result>((resolve, reject: (error: Models.MysqlError) => void) => {
      pool.getConnection((error: mysql.MysqlError, connection: mysql.PoolConnection) => {
        // 如果连接出错 抛出错误
        if (error) {
          const reuslt: Models.MysqlError = {
            error,
            msg: '数据库连接出错:' + ' ' + error.message,
          }
          reject(reuslt)
        }

        const callback: mysql.queryCallback = (err, results?: any, fields?: mysql.FieldInfo[]) => {
          connection.release()
          if (err) {
            const result: Models.MysqlError = {
              error: err,
              msg: err.sqlMessage || '数据库增删改查出错',
            }
            reject(result)
          } else {
            const result: Models.Result = {
              msg: 'ok',
              state: 1,
              // 将数据库得字段,有下划线改为驼峰
              results: results instanceof Array ? results.map(lineToHumpObject) : results,
              fields: fields || [],
            }
            resolve(result)
          }
        }
        if (useLog) {
          // 记录sql日志
          logger.info(`执行sql：${command}`)
        }
        // 执行mysql语句
        if (value) {
          pool.query(command, value, callback)
        } else {
          pool.query(command, callback)
        }
      })
    }).catch((error) => {
      throw new DataBaseFailed({ msg: error.msg })
    })
  } catch (error) {
    throw new DataBaseFailed()
  }
}
